# Project 2: LEDの明るさ調整 ### **1.説明** 前回のレッスンでは、LEDのオン・オフ制御と点滅を行いました。 このプロジェクトでは、PWMを使ってLEDの明るさを制御し、呼吸するような効果をシミュレートします。 PWMはデジタル手段でアナログ出力を制御する方法です。デジタル制御を用いて異なるデューティサイクルの方形波(高レベルと低レベルを絶えず切り替える信号)を生成し、アナログ出力を制御します。一般的に、ポートの入力電圧は0Vと5Vです。 もし3Vが必要だったら?あるいは1V、3V、3.5Vの切り替えが必要だったら?抵抗を常に変えることはできません。そこでPWMを利用します。 ![bbcfcb9ae56abb7e80ee587246fc4be9](media/A14.gif) Arduinoのデジタルポートの電圧出力はLOWとHIGHの2つだけで、それぞれ0Vと5Vに対応します。LOWを0、HIGHを1と定義し、Arduinoが1秒間に500回0または1の信号を出力するとします。 もし500回すべてが1なら5V、すべてが0なら0Vです。このように010101010101と出力すると、出力ポートは2.5Vとなり、映画の表示に似ています。私たちが見る映画は完全に連続しているわけではなく、実際には1秒間に25枚の画像を出力しています。この場合、人間には連続して見えますが、PWMも同様です。異なる電圧を得るには、0と1の比率を制御する必要があります。単位時間あたりに出力される0と1の信号が多いほど、制御はより正確になります。 PWMはデジタル手段でアナログ量を得る技術です。デジタル制御により方形波を形成し、方形波信号はオンとオフの2状態(高レベルと低レベル)だけを持ちます。0〜5Vの電圧はオンとオフの時間比率を制御することでシミュレートできます。オンの時間(技術的には高レベル時間)をパルス幅と呼ぶため、PWMはパルス幅変調とも呼ばれます。 緑の縦棒は方形波の1周期を表しています。各analogWrite(value)に書かれた値はパーセンテージに対応し、デューティサイクルとも呼ばれます。このパーセンテージは1周期における高レベルの時間比率、すなわちデューティサイクル = 高レベル時間 / 周期時間を指します。 図では上から下に向かって、最初の方形波のデューティサイクルは0%、対応する値は0で、LEDの明るさは最も低く、つまり消灯状態です。高レベルが長く続くほど明るくなります。したがって、最後のデューティサイクル100%の値は255で、LEDは最も明るくなります。50%は明るさの半分、25%はより暗くなります。 PWMはLEDの明るさ調整やモーターの回転速度調整に多く使われ、モーターで駆動される車輪の速度も簡単に制御できます。Arduinoロボットを操作するとき、PWMの利点がよりよく実感できます。 ### **2.部品** | Development Board *1 | 8833 Motor Driver *1 | Red LED Module*1 | | :--------------------------------------: | :--------------------------------------: | :----------------------: | | ![img](media/A8.jpg) | ![img](media/A9.jpg) | ![img](media/A10.jpg) | | 3P Dupont Wire*1 | USB Cable*1 | | | ![img](media/A11.jpg) | ![img](media/A12.jpg) | | ### **3.配線図** 配線はそのまま変更しないでください。 ![image-20250508161123490](media/A13.png) ### **4.テストコード** ```c //***************************************************************** /* keyestudio 4wd BT Car lesson 2.1 pwm http://www.keyestudio.com */ int ledPin = 9; // D9にLEDピンを定義 int value; void setup () { pinMode (ledPin, OUTPUT); // ledPinを出力として初期化 } void loop () { for (value = 0; value <255; value = value + 1) { analogWrite (ledPin, value); // LEDが徐々に明るく点灯する delay (5); // 5ms待機 } for (value = 255; value> 0; value = value-1) { analogWrite (ledPin, value); // LEDが徐々に暗くなる delay (5); // 5ms待機 } } //***************************************************************** ``` ### **5.テスト結果** コードをV4.0ボードに正常にアップロードした後、配線図に従って配線を接続し、USBケーブルでコンピュータと接続してボードに電源を供給します。電源を入れると、LEDが明るさを徐々に変化させ、人の呼吸のようにすぐに点灯・消灯するのではなく、徐々に明るくなったり暗くなったりするのが見えます。 ### **6.コード説明** 特定の文を繰り返す必要がある場合、for文を使うことができます。 for文の形式は以下の通りです: ![image-20250508162458776](media/A15.png) FORの繰り返し順序: ラウンド1:1 → 2 → 3 → 4 ラウンド2:2 → 3 → 4 … 数字2が成立しなくなるまで、「for」ループは終了します。 この順序を理解したら、コードに戻りましょう: **for (int value = 0; value \< 255; value=value+1)** **for (int value = 255; value \>0; value=value-1)** この2つの“for”文は、valueを0から255まで増加させ、次に255から0まで減少させ、また255まで増加させる…という無限ループを作ります。 次に新しい関数 ----- analogWrite() があります。 デジタルポートは0か1の2つの状態しか持たないことは知っています。では、どうやってアナログ値をデジタル値に送るのでしょうか?ここでこの関数が必要になります。Arduinoボードを観察して、“\~”とマークされた6つのピンがPWM信号を出力できることを見つけましょう。 関数の形式は以下の通りです: **analogWrite(pin,value)** analogWrite()はPWMポートに0〜255の範囲のアナログ値を書き込むために使われます。値は0〜255の範囲です。PWM機能を持つデジタルピン(例えばピン3、5、6、9、10、11)にのみ書き込めることに注意してください。 PWMはデジタル方式でアナログ量を得る技術です。デジタル制御は方形波を形成し、方形波信号はオンとオフの2つの状態(高レベルまたは低レベル)しか持ちません。オンとオフの時間比率を制御することで、0〜5Vの電圧をシミュレートできます。オンの時間(学術的には高レベルと呼ばれる)をパルス幅と呼び、PWMはパルス幅変調とも呼ばれます。 以下の5つの方形波を通じて、PWMについてさらに学びましょう。 ![image-20250508162529349](media/A16.png) 上図では、緑の線が1周期を表し、analogWrite()の値はDuty Cycle(デューティサイクル)と呼ばれる割合に対応します。デューティサイクルは周期内で高レベルが占める時間の割合を意味します。上から順に、最初の方形波のデューティサイクルは0%で対応する値は0です。 LEDの明るさは最も低く、つまり消灯状態です。高レベルの時間が長いほどLEDは明るくなります。したがって、最後のデューティサイクルは100%で255に対応し、LEDは最も明るくなります。50%は半分の明るさ、25%はより暗いことを意味します。 PWMはLEDの明るさ調整やモーターの回転速度調整に多く使われます。 スマートロボットカーの制御において重要な役割を果たします。次のプロジェクトを学ぶのが待ちきれないことでしょう。 **7.拡張練習** delayの値を変更し、ピンはそのままにして、LEDの変化を観察してみましょう。 ```c //*********************************************************** /* keyestudio 4wd BT Car lesson 2.2 pwm http://www.keyestudio.com */ int ledPin = 9; // D9にLEDピンを定義 void setup () { pinMode(ledPin, OUTPUT); // ledPinを出力として初期化 } void loop () { for (int value = 0; value <255; value = value + 1) { analogWrite (ledPin, value); // LEDが徐々に明るく点灯する delay (30); // 30ms待機 } for (int value = 255; value> 0; value = value-1) { analogWrite (ledPin, value); // LEDが徐々に暗くなる delay (30); // 30ms待機 } } //*********************************************************** ``` 開発ボードにコードをアップロードすると、LEDがよりゆっくり点滅します。